#ifndef SDK_OHOS_OHOS_DATA_CHANNEL_H_
#define SDK_OHOS_OHOS_DATA_CHANNEL_H_

#include <memory>
#include <string>
#include "api/ohos_data_channel_interface.h"
#include "rtc_base/logging.h"
#include "api/data_channel_interface.h"
#include "rtc_base/synchronization/mutex.h"

namespace ohoswebrtc {

class OHOSDataChannelDelegateAdapter : public webrtc::DataChannelObserver {
 public:
    OHOSDataChannelDelegateAdapter() {}

    virtual ~OHOSDataChannelDelegateAdapter();

    void RegisterObserver(OHOSDataChannelObserver *observer);

    void UnRegisterObserver();
    
    void OnStateChange() override;

    void OnMessage(const webrtc::DataBuffer& buffer) override;

    void OnBufferedAmountChange(uint64_t sent_data_size) override;

 private:
    OHOSDataChannelObserver* data_channel_observer_;
};

class OHOSDataChannel : public OHOSDataChannelInterface {
  public:
    OHOSDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel);
    virtual ~OHOSDataChannel();
    /** The label attribute represents a label that can be used to distinguish this
     *  DataChannel object from other DataChannel objects
     */
    std::string label() const override;

    /** The accessors below simply return the properties from the DataChannelInit.
     * the data channel was constructed with.
     */
    bool reliable() const override;

    bool ordered() const override;
    
    uint16_t maxRetransmitTime() const override;
    uint16_t maxRetransmits() const override;
    absl::optional<int> maxRetransmitsOpt() const override;
    absl::optional<int> maxPacketLifeTime() const override;
    std::string protocol() const override;
    bool negotiated() const override;

    /** Returns the ID from the DataChannelInit, if it was negotiated out-of-band.
     * If negotiated in-band, this ID will be populated once the DTLS role is
     * determined, and until then this will return -1.
     */
    int id() const override;

    /** The state of the data channel.*/
    webrtc::DataChannelInterface::DataState state() const override;

    uint32_t messages_sent() const override;
    uint64_t bytes_sent() const override;
    uint32_t messages_received() const override;
    uint64_t bytes_received() const override;
  
    /** The number of bytes of application data that have been queued using 
     *`sendData:` but that have not yet been transmitted to the network.
     */
    uint64_t buffered_amount() const override;

    /** Begins the graceful data channel closing procedure. */
    void Close() override;

    /** Sends `data` to the remote peer. If the data can't be sent at the SCTP
     * level (due to congestion control), it's buffered at the data channel level,
     * up to a maximum of MaxSendQueueSize().
     * Returns false if the data channel is not in open state or if the send
     * buffer is full.
     */
    void Send(const webrtc::DataBuffer& buffer) override;
    void Send(const uint8_t* data, uint32_t size, bool binary = false) override;
    void SendAsync(webrtc::DataBuffer buffer,
                         absl::AnyInvocable<void(webrtc::RTCError) &&> on_complete) override;
    void RegisterObserver(OHOSDataChannelObserver* observer) override;
    void UnRegisterObserver() override;

  private:
    std::string label_;
    rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel_;
    std::unique_ptr<OHOSDataChannelDelegateAdapter> adapter_observer_;
};

}

#endif